import os
import base64
import time
import sys
from dotenv import load_dotenv
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from openai import OpenAI

# 添加项目根目录到Python路径，以便导入config_reader模块
current_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(os.path.dirname(current_dir))
sys.path.append(project_root)

from config_reader import get_deepseek_api_key

# 加载环境变量
load_dotenv()

class EnvInteractAgent:
    def __init__(self):
        # 初始化浏览器（无头模式：不显示浏览器窗口，后台运行）
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument("--headless=new")  # 无头模式
        chrome_options.add_argument("--window-size=1920,1080")  # 设定窗口大小（确保元素可见）
        self.driver = webdriver.Chrome(options=chrome_options)
        self.wait = WebDriverWait(self.driver, 10)  # 元素等待超时时间：10秒
        
        # 初始化DeepSeek客户端
        try:
            api_key = get_deepseek_api_key()
            self.client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com")
        except Exception as e:
            print(f"❌ 初始化DeepSeek客户端失败：{str(e)}")
            raise

    def _screenshot_to_base64(self, save_path="page_screenshot.png") -> str:
        """
        功能：截取当前网页截图，转为 base64 编码（用于 DeepSeek-VL2 识别）
        返回：base64 字符串
        """
        self.driver.save_screenshot(save_path)
        with open(save_path, "rb") as image_file:
            base64_str = base64.b64encode(image_file.read()).decode("utf-8")
        return base64_str

    def _ask_multimodal(self, base64_image: str, user_query: str) -> str:
        """
        功能：调用 DeepSeek-VL2 多模态模型，识别网页元素并生成操作建议
        参数：base64_image（网页截图）、user_query（用户目标）
        返回：LLM 生成的操作步骤（如"定位姓名输入框，输入'张三'"）
        """
        try:
            response = self.client.chat.completions.create(
                model="deepseek-vl",  # 使用DeepSeek-VL2模型
                messages=[
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": user_query},
                            {
                                "type": "image_url",
                                "image_url": {"url": f"data:image/png;base64,{base64_image}"},
                            },
                        ],
                    }
                ],
                max_tokens=500,
                temperature=0.2,  # 低随机性，确保操作建议精准
            )
            return response.choices[0].message.content.strip()
        except Exception as e:
            print(f"❌ DeepSeek-VL2调用失败：{str(e)}")
            return f"❌ 无法分析图像：{str(e)}"

    def _execute_action(self, action_steps: str, form_data: dict):
        """
        功能：解析 LLM 生成的操作步骤，执行浏览器操作
        参数：action_steps（LLM 操作建议）、form_data（表单数据，如姓名、邮箱）
        """
        # 示例：解析操作步骤（实际项目可用更复杂的指令解析逻辑）
        actions = action_steps.split("\n")
        for action in actions:
            if "姓名输入框" in action and "输入" in action:
                try:
                    # 定位姓名输入框（优先按 ID，无 ID 按 name，再按 XPath）
                    name_input = self.wait.until(
                        EC.presence_of_element_located(
                            (By.ID, "name")  # 假设表单姓名输入框 ID 为 "name"
                        )
                    )
                    name_input.send_keys(form_data["name"])
                    print(f"✅ 执行：姓名输入框填入 {form_data['name']}")
                except (TimeoutException, NoSuchElementException):
                    print("❌ 未找到姓名输入框，尝试按 name 定位...")
                    name_input = self.driver.find_element(By.NAME, "username")
                    name_input.send_keys(form_data["name"])

            elif "邮箱输入框" in action and "输入" in action:
                email_input = self.wait.until(
                    EC.presence_of_element_located((By.ID, "email"))
                )
                email_input.send_keys(form_data["email"])
                print(f"✅ 执行：邮箱输入框填入 {form_data['email']}")

            elif "密码输入框" in action and "输入" in action:
                pwd_input = self.wait.until(
                    EC.presence_of_element_located((By.ID, "password"))
                )
                pwd_input.send_keys(form_data["password"])
                print(f"✅ 执行：密码输入框填入 ******")

            elif "同意条款" in action and "勾选" in action:
                agree_checkbox = self.wait.until(
                    EC.presence_of_element_located((By.ID, "agree_terms"))
                )
                if not agree_checkbox.is_selected():
                    agree_checkbox.click()
                    print(f"✅ 执行：勾选同意条款")

            elif "提交按钮" in action and "点击" in action:
                submit_btn = self.wait.until(
                    EC.element_to_be_clickable((By.ID, "submit_btn"))
                )
                submit_btn.click()
                print(f"✅ 执行：点击提交按钮")
                time.sleep(3)  # 等待提交结果加载

    def run(self, target_url: str, user_query: str, form_data: dict):
        """
        主流程：感知→决策→执行
        参数：target_url（目标网页 URL）、user_query（用户目标）、form_data（表单数据）
        """
        try:
            # 1. 访问目标网页（模拟表单页面，实际可替换为真实 URL）
            print(f"📌 第一步：访问目标网页 {target_url}")
            self.driver.get(target_url)
            time.sleep(2)  # 等待页面加载

            # 2. 感知环境：截图并调用 DeepSeek-VL2 识别元素
            print(f"📌 第二步：截图识别网页元素")
            base64_image = self._screenshot_to_base64()
            action_steps = self._ask_multimodal(
                base64_image=base64_image,
                user_query=user_query
            )
            print(f"🔍 DeepSeek-VL2 生成的操作步骤：\n{action_steps}")

            # 3. 执行操作：根据 LLM 建议填写表单并提交
            print(f"📌 第三步：执行浏览器操作")
            self._execute_action(action_steps=action_steps, form_data=form_data)

            # 4. 验证结果：截图确认提交状态
            print(f"📌 第四步：验证提交结果")
            result_screenshot = self._screenshot_to_base64("result_screenshot.png")
            result_check = self._ask_multimodal(
                base64_image=result_screenshot,
                user_query="判断表单是否提交成功？如果页面有提示信息，请提取提示内容。"
            )
            print(f"✅ 提交结果：\n{result_check}")

        except Exception as e:
            print(f"❌ 执行出错：{str(e)}")
        finally:
            # 关闭浏览器
            self.driver.quit()
            print(f"📌 流程结束，关闭浏览器")

# ------------------- 示例调用 -------------------
if __name__ == "__main__":
    # 目标配置（可替换为真实表单 URL）
    TARGET_URL = "https://example.com/simulate-form"  # 模拟注册表单页面
    USER_QUERY = """
    你需要帮我识别这个网页的注册表单元素，并生成操作步骤：
    1. 找到姓名输入框、邮箱输入框、密码输入框；
    2. 找到“同意用户条款”复选框和“提交”按钮；
    3. 按“先填输入框→勾选条款→点击提交”的顺序，生成每一步的操作描述（需包含元素定位方式，如 ID、name）。
    """
    # 表单数据（需填写的内容）
    FORM_DATA = {
        "name": "张三",
        "email": "zhangsan@example.com",
        "password": "Test123456!"
    }

    # 启动环境交互 Agent
    agent = EnvInteractAgent()
    agent.run(
        target_url=TARGET_URL,
        user_query=USER_QUERY,
        form_data=FORM_DATA
    )